package com.kakarote.oa.common.repetitionstrategy;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.kakarote.oa.entity.BO.OaEventDTO;
import com.kakarote.oa.entity.PO.OaEvent;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * 每天重复策略
 *
 * @author hmb
 */
@Component("Daily")
public class DailyStrategy extends AbstractRepetitionStrategy {

    @Override
    public List<OaEventDTO> processQuery(List<OaEvent> oaEventList, long startTime, long endTime) {
        List<OaEventDTO> eventList = new ArrayList<>();
        for (OaEvent oaEvent : oaEventList) {
            LocalDateTime startDate = oaEvent.getRepeatStartTime();
            LocalDateTime endDate = oaEvent.getRepeatEndTime();
            Integer repeatRate = oaEvent.getRepeatRate();
            //计算出日程的时间差
            int betweenDay = (int) LocalDateTimeUtil.between(oaEvent.getStartTime(), oaEvent.getEndTime()).toDays();
            //前端传的开始时间向前推移相应的时间差  好计算前几天的日程
            long startTime1 = startTime - DAY_TIME * betweenDay;
            //计算开始次数和结束次数

            int betweenStartDay = (int) LocalDateTimeUtil.between(startDate, LocalDateTimeUtil.of(startTime1)).toDays();
            int betweenEndDay = (int) LocalDateTimeUtil.between(startDate, LocalDateTimeUtil.of(endTime)).toDays();
            if (betweenEndDay < 0) {
                continue;
            }
            //开始时间大于前端传来的开始时间  次数就从零开始
            if (betweenStartDay < 0) {
                betweenStartDay = 0;
            }
            //计算次数（当前时间-日程开始时间）/循环频率 + 1 =次数
            int startCount = betweenStartDay / repeatRate;
            int endCount = betweenEndDay / repeatRate + 1;
            for (int i = startCount; i < endCount; i++) {
                int offset = repeatRate * i;
                LocalDateTime offStartTime = LocalDateTimeUtil.offset(oaEvent.getStartTime(), offset, ChronoUnit.DAYS);
                LocalDateTime offEndTime = LocalDateTimeUtil.offset(oaEvent.getEndTime(), offset, ChronoUnit.DAYS);
                if (LocalDateTimeUtil.toEpochMilli(offEndTime) < startTime) {
                    continue;
                }
                if (isContinue(oaEvent, offStartTime, endDate)) {
                    continue;
                }
                OaEventDTO oaEventDTO = transfer(oaEvent);
                oaEventDTO.setStartTime(LocalDateTimeUtil.toEpochMilli(offStartTime));
                oaEventDTO.setEndTime(LocalDateTimeUtil.toEpochMilli(offEndTime));
                eventList.add(oaEventDTO);
            }
        }
        return eventList;
    }

    @Override
    protected LocalDateTime processCountTime(LocalDateTime startTime, int offset) {
        return LocalDateTimeUtil.offset(startTime, offset, ChronoUnit.DAYS);
    }


}
